package com.portme.server;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;
import com.portme.client.GreetingService;
import com.portme.server.pojos.CustomTab;
import com.portme.server.pojos.HomePage;
import com.portme.server.pojos.Post;
import com.portme.server.pojos.Profile;
import com.portme.shared.ClientCustomTab;
import com.portme.shared.ClientHomePage;
import com.portme.shared.ClientPost;
import com.portme.shared.FieldVerifier;
import com.portme.shared.LoginInfo;
import com.portme.shared.UserProfile;

/**
 * The server side implementation of the RPC service.
 */
@SuppressWarnings("serial")
public class GreetingServiceImpl extends RemoteServiceServlet implements
		GreetingService {

	public String greetServer(String input) throws IllegalArgumentException {
		// Verify that the input is valid. 
		if (!FieldVerifier.isValidName(input)) {
			// If the input is not valid, throw an IllegalArgumentException back to
			// the client.
			throw new IllegalArgumentException(
					"Name must be at least 4 characters long");
		}

		String serverInfo = getServletContext().getServerInfo();
		String userAgent = getThreadLocalRequest().getHeader("User-Agent");

		// Escape data from the client to avoid cross-site script vulnerabilities.
		input = escapeHtml(input);
		userAgent = escapeHtml(userAgent);

		return "Hello, " + input + "!<br><br>I am running " + serverInfo
				+ ".<br><br>It looks like you are using:<br>" + userAgent;
	}

	/**
	 * Escape an html string. Escaping data received from the client helps to
	 * prevent cross-site script vulnerabilities.
	 * 
	 * @param html the html string to escape
	 * @return the escaped string
	 */
	private String escapeHtml(String html) {
		if (html == null) {
			return null;
		}
		return html.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
				.replaceAll(">", "&gt;");
	}

	@Override
	public LoginInfo getLoginUrl() throws Exception {
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        LoginInfo loginInfo = null;
        
        try {
        	if (user != null) {
                loginInfo = new LoginInfo(null, userService.createLogoutURL("/#home"), true);
                loginInfo.setUsername(user.getEmail());
                DAO dao = new DAO();
                Profile profile = dao.savePuser(user.getEmail());
                Map<Long, CustomTab> tabs = dao.getAllTabs(profile.getCustomTabs());
                Iterator<Entry<Long, CustomTab>> itr = tabs.entrySet().iterator();
                ArrayList<ClientCustomTab> clientTabs = new ArrayList<ClientCustomTab>();
                while(itr.hasNext()) {
                	Entry<Long, CustomTab> entry = itr.next();
                	
                	HashMap<Long,ClientPost> clientPosts = new HashMap<Long,ClientPost>();
                	Map<Long, Post> posts = dao.getAllPostsInTab(entry.getValue().getPosts());
                	Iterator<Entry<Long, Post>> it = posts.entrySet().iterator();
                	while(it.hasNext()) {
                		Entry<Long, Post> ent = it.next();
                		clientPosts.put(ent.getValue().getId(),new ClientPost(ent.getValue().getId(), ent.getValue().getTitle(), ent.getValue().getText()));
                	}
                	
                	ClientCustomTab clientTab = new ClientCustomTab(entry.getValue().getTitle(),entry.getKey(), clientPosts);
                	clientTabs.add(clientTab);
                }
                
                //Get user HomePage
                ClientHomePage homePage = getClientHomePage(profile.getHomePage());
                UserProfile userProfile = new UserProfile(user.getEmail(), clientTabs, profile.getTheme(), homePage);
                loginInfo.setProfile(userProfile);
            } else {
            	loginInfo = new LoginInfo(userService.createLoginURL("/callback"), null, false);
            }
		} catch (Exception e) {
			e.printStackTrace();
		}
        return loginInfo;
	}

	@Override
	public ClientCustomTab createTab(String tabTitle) throws Exception {
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if(user != null) {
        	DAO dao = new DAO();
        	CustomTab addedTab = dao.createTab(tabTitle, user.getEmail());
        	
        	HashMap<Long,ClientPost> clientPosts = new HashMap<Long,ClientPost>();
        	Map<Long, Post> posts = dao.getAllPostsInTab(addedTab.getPosts());
        	Iterator<Entry<Long, Post>> it = posts.entrySet().iterator();
        	while(it.hasNext()) {
        		Entry<Long, Post> ent = it.next();
        		clientPosts.put(ent.getValue().getId(),new ClientPost(ent.getValue().getId(), ent.getValue().getTitle(), ent.getValue().getText()));
        	}
        	
        	ClientCustomTab clientTab = new ClientCustomTab(addedTab.getTitle(),addedTab.getId(), clientPosts);
        	return clientTab;
        } else {
        	return null;
        }
	}

	@Override
	public UserProfile getUserPortfolio(String user) {
		DAO dao = new DAO();
        Profile profile = dao.getProfile(user+"@gmail.com");
        Map<Long, CustomTab> tabs = dao.getAllTabs(profile.getCustomTabs());
        Iterator<Entry<Long, CustomTab>> itr = tabs.entrySet().iterator();
        ArrayList<ClientCustomTab> clientTabs = new ArrayList<ClientCustomTab>();
        while(itr.hasNext()) {
        	Entry<Long, CustomTab> entry = itr.next();
        	
        	HashMap<Long,ClientPost> clientPosts = new HashMap<Long,ClientPost>();
        	Map<Long, Post> posts = dao.getAllPostsInTab(entry.getValue().getPosts());
        	Iterator<Entry<Long, Post>> it = posts.entrySet().iterator();
        	while(it.hasNext()) {
        		Entry<Long, Post> ent = it.next();
        		clientPosts.put(ent.getValue().getId(),new ClientPost(ent.getValue().getId(), ent.getValue().getTitle(), ent.getValue().getText()));
        	}
        	
        	ClientCustomTab clientTab = new ClientCustomTab(entry.getValue().getTitle(),entry.getKey(), clientPosts);
        	clientTabs.add(clientTab);
        }
        
        //Get user HomePage
        ClientHomePage homePage = getClientHomePage(profile.getHomePage());
        
        UserProfile userProfile = new UserProfile(user+"@gmail.com", clientTabs, profile.getTheme(), homePage);
		return userProfile;
	}

	@Override
	public ClientPost createPost(Long tabId, String title, String text) throws Exception {
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if(user != null) {
        	DAO dao = new DAO();
        	Post post = dao.createPost(tabId, title, text);
        	ClientPost clientPost = new ClientPost(post.getId(), post.getTitle(), post.getText());
        	return clientPost;
        } else {
        	return null;
        }
	}

	@Override
	public String setTheme(String themeName) throws Exception {
		
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        DAO dao = new DAO();
        
        //return profile.setTheme(themeName);
		return dao.setTheme(themeName, user.getEmail());
	}



	@Override
	public ClientHomePage setHomePage(String siteTitle, String pitchText, String about,
			String contact) {
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        DAO dao = new DAO();
        HomePage homePage = dao.setHomePage(siteTitle, pitchText, about, contact, user.getEmail());    
        ArrayList<ClientPost> clientPosts = getClientPosts(homePage.getPosts());
        ClientHomePage clientHomePage = new ClientHomePage(siteTitle, pitchText, about, contact, clientPosts);
		return clientHomePage;
	}

	@Override
	public ClientPost addPostToHomePage(Long postId) {
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        DAO dao = new DAO();
		dao.addPostToHomePage(postId, user.getEmail());
		Post post = dao.getPost(postId);
		ClientPost clientPost = new ClientPost(post.getId(), post.getTitle(), post.getText());
    	return clientPost;
	}
	
	private ArrayList<ClientPost> getClientPosts(List<Long> postIds)
	{
		DAO dao = new DAO();
		ArrayList<ClientPost> clientPosts = new ArrayList<ClientPost>();
    	Map<Long, Post> posts = dao.getAllPostsInTab(postIds);
    	Iterator<Entry<Long, Post>> it = posts.entrySet().iterator();
    	while(it.hasNext()) {
    		Entry<Long, Post> ent = it.next();
    		clientPosts.add(new ClientPost(ent.getValue().getId(), ent.getValue().getTitle(), ent.getValue().getText()));
    	}
    	return clientPosts;
	}
	
	private ClientHomePage getClientHomePage(Long homePageId) {
		DAO dao = new DAO();
		HomePage homePage = dao.getHomePage(homePageId);
		ArrayList<ClientPost> clientPosts = getClientPosts(homePage.getPosts()); 
		ClientHomePage clientHomePage = new ClientHomePage(homePage.getSiteTitle(), homePage.getPitchSentence(), homePage.getAbout(), homePage.getContact(), clientPosts);
		return clientHomePage;
	}

	@Override
	public ClientPost editPost(Long postId, String title, String text) {
		// TODO Auto-generated method stub
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if(user != null) {
        	DAO dao = new DAO();
        	Post post = dao.editPost(postId, title, text);
        	ClientPost clientPost = new ClientPost(post.getId(), post.getTitle(), post.getText());
        	return clientPost;
        } else {
        	return null;
        }
	}
	
	@Override
	public Boolean deletePost(Long postId) {
		// TODO Auto-generated method stub
		UserService userService = UserServiceFactory.getUserService();
        User user = userService.getCurrentUser();
        if(user != null) {
        	DAO dao = new DAO();
        	boolean isDeleted = dao.deletePost(postId);
        	
        	return isDeleted;
        } else {
        	return false;
        }
	}
}
